package com.muchenx.util;

import com.muchenx.App;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import org.kordamp.bootstrapfx.BootstrapFX;

import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * UI组件创建工具类
 */
public final class UIComponentUtil {

    public static <T> T loadComponent(String componentClassPath) throws IOException {
        return new FXMLLoader(App.class.getResource(componentClassPath))
                .load();
    }

    public static void focus(VBox root) {
        Optional<Node> opt = root.getChildren().stream()
                .filter(e -> (e instanceof TextField) || (e instanceof TextArea)).findFirst();
        if (opt.isPresent()) {
            opt.get().requestFocus();
            return;
        }
        List<HBox> list = root.getChildren().stream()
                .filter(e -> e instanceof HBox)
                .flatMap(node -> Stream.of((HBox) node))
                .toList();
        Optional<HBox> first = list.stream().filter(hBox -> hBox.getChildren().stream().anyMatch(e -> (e instanceof TextField) || (e instanceof TextArea))).findFirst();
        if (first.isPresent()) {
            Optional<Node> optChild = first.get().getChildren().stream().filter(e -> (e instanceof TextField) || (e instanceof TextArea)).findFirst();
            optChild.ifPresent(Node::requestFocus);
        }
    }

    public static void cleanTextFields(VBox root) {
        root.getChildren().forEach(item -> {
            if (item instanceof HBox) {
                ((HBox) item).getChildren().forEach(c -> {
                    if (c instanceof TextField) {
                        ((TextField) c).clear();
                    }
                });
            } else if (item instanceof TextField) {
                ((TextField) item).clear();
            }
        });
    }

    public static void errorAlert(String msg) {
        Alert alert = new Alert(Alert.AlertType.ERROR, msg, ButtonType.CLOSE);
        UIComponentUtil.addIcon((Stage) alert.getDialogPane().getScene().getWindow());
        alert.setTitle("温馨提示");
        alert.setHeaderText(null);
        alert.setResizable(true);
        alert.showAndWait();
    }

    public static void infoAlert(String msg) {
        Alert alert = new Alert(Alert.AlertType.INFORMATION, msg, ButtonType.CLOSE);
        UIComponentUtil.addIcon((Stage) alert.getDialogPane().getScene().getWindow());
        alert.setTitle("温馨提示");
        alert.setHeaderText(null);
        alert.setResizable(true);
        alert.showAndWait();
    }

    public static Alert createCustomConfirm(Node... nodes) {
        return createCustomConfirm("信息确认", 200, 100, nodes);
    }

    public static Alert createCustomConfirm(String title, Node... nodes) {
        return createCustomConfirm(title, 200, 100, nodes);
    }

    public static Alert createCustomConfirm(String title, double width, double height, Node... nodes) {
        Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
        alert.setResizable(false);
        alert.setTitle(title);
        alert.setHeaderText(null);
        alert.setGraphic(null);
        addIcon((Stage) alert.getDialogPane().getScene().getWindow());

        if (nodes.length > 0) {
            VBox vBox = new VBox();
            vBox.setFillWidth(true);
            vBox.getChildren().addAll(nodes);
            alert.getDialogPane().setContent(vBox);
        }
        alert.getDialogPane().setPrefWidth(width);
        alert.getDialogPane().setPrefHeight(height);
        return alert;
    }

    public static Stage stage(String title) {
        Stage stage = new Stage();
        addIcon(stage);
        stage.setTitle(title);
        stage.initStyle(StageStyle.DECORATED);
        return stage;
    }

    public static void addIcon(Stage currentState) {
        currentState.getIcons().add(new Image(Objects.requireNonNull(
                UIComponentUtil.class.getResourceAsStream("/img/avatar.png"))));
    }

    public static Scene scene(Parent parent) {
        Scene scene = new Scene(parent,
                Screen.getPrimary().getVisualBounds().getWidth() / 2,
                Screen.getPrimary().getVisualBounds().getHeight() / 2);
        scene.setFill(Color.DARKTURQUOISE);
        scene.getStylesheets().add(BootstrapFX.bootstrapFXStylesheet());
        return scene;
    }

    public static Button button(String title) {
        Button button = new Button();
        button.getStyleClass().setAll("btn", "btn-info");
        button.setStyle("-fx-text-alignment: center;-fx-alignment: center;");
        button.setCursor(Cursor.HAND);
        button.setText(title);
        return button;
    }

    public static HBox wrapTextField(TextField textField, String labelTitle) {
        return wrapTextField(textField, labelTitle, 80);
    }

    public static HBox wrapTextField(TextField textField, String labelTitle, double labelWith) {
        HBox hBox = new HBox();
        hBox.setFillHeight(true);
        hBox.setPadding(new Insets(20, 0, 0, 0));
        hBox.setAlignment(Pos.CENTER);
        hBox.setSpacing(10);
        Label label = new Label(labelTitle);
        label.setTooltip(new Tooltip(labelTitle));
        label.setPrefWidth(labelWith);
        label.setAlignment(Pos.CENTER_RIGHT);
        label.setTextOverrun(OverrunStyle.CENTER_WORD_ELLIPSIS);
        hBox.getChildren().addAll(label, textField);
        HBox.setHgrow(textField, Priority.ALWAYS);// 子节点自适应宽度
        return hBox;
    }

    public static HBox wrapTextField(TextField textField) {
        HBox hBox = new HBox();
        hBox.setFillHeight(true);
        hBox.setPadding(new Insets(20, 0, 0, 0));
        hBox.setAlignment(Pos.CENTER);
        hBox.getChildren().add(textField);
        HBox.setHgrow(textField, Priority.ALWAYS);// 子节点自适应宽度
        return hBox;
    }

    public static TextField textField(String tip) {
        return textField(tip, null);
    }

    public static TextField textField(String tip, String defaultValue) {
        TextField textField = new TextField(defaultValue);
        textField.setPromptText(tip);
        textField.setTooltip(new Tooltip(tip));
        textField.setAlignment(Pos.CENTER);
        return textField;
    }
}
